<?php

namespace App\Models;

use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;

class DispatchRule extends Model implements Sortable
{
    use HasFactory;
    use SortableTrait;
    use HasDateTimeFormatter;

    protected $sortable = [
        // 设置排序字段名称
        'order_column_name' => 'order',
        // 是否在创建时自动排序，此参数建议设置为true
        'sort_when_creating' => true,
    ];


    const CLUE_FIELDS = [
        'name' => '客户姓名',
        'phone' => '客户电话',
        'source' => '来源',
        'url' => '链接',
        'remark' => '备注',
        'ip' => 'IP',
        'location' => '城市',
        'question_data' => '问题内容',
        'site_name' => '站点名称',
        'ad_name' => '计划名称',
        'ad_id' => '计划ID',
        'post_date' => '提交时间',
    ];

    const OPERATOR = [
        'like' => '包含',
        'eq' => '等于',
        'gt' => '大于',
        'lt' => '小于',
        'regex' => '正则匹配',
    ];

    const TYPE_OPTIONS = [
        0 => '适用于所有线索',
        1 => '适用符合于条件线索',
    ];

    const RULE_TYPE_OPTIONS = [
        0 => '满足任意一条',
        1 => '满足所有条件',
    ];

    private static $rules;

    protected $fillable = [
        'rules',
        'name',
        'group_id',
        'order',
        'type',
        'rule_type',
    ];

    protected $casts = [
        'rules' => 'json',
    ];

    public function userGroup(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(UserGroup::class, 'group_id', 'id');
    }

    public static function getRules()
    {
        return static::query()
            ->orderBy('order', 'desc')->get();
//        if (!static::$rules)
//
//            return static::$rules;
    }

    public static function checkOperator($operator, $fieldValue, $value)
    {
        if (!is_string($fieldValue))
            $fieldValue = json_encode($fieldValue, JSON_UNESCAPED_UNICODE);

        switch ($operator) {
            case "like":
                if (Str::contains($fieldValue, $value))
                    return true;
                break;
            case "eq":
                if ($value === $fieldValue)
                    return true;
                break;
            case "gt":
                if ($fieldValue > $value)
                    return true;
                break;
            case "lt":
                if ($fieldValue < $value)
                    return true;
                break;
            case "regex":
                if (preg_match($value, $fieldValue))
                    return true;
                break;
        }
        return false;
    }

    public static function validateClueOfRule($clue, $rules, $rule_type)
    {
        $result = false;
        foreach ($rules as $rule) {
            $field = $rule['field'];
            $fieldValue = data_get($clue, $field);
            $value = $rule['value'];
            $operator = $rule['operator'];
            if ($field === 'source') {
                $options = MediaSource::toOptions();
                $fieldValue = data_get($options, $fieldValue);
            }
            // 结果判断
            // 0 : 任意条件满足
            // 1 : 全部条件同时满足
            //
            $checkOperator = static::checkOperator($operator, $fieldValue, $value);
            Log::info("=============> 分配判断", [
                "field" => $fieldValue,
                'operator' => $operator,
                "value" => $value,
                "checkOperator" => $checkOperator,
                "rule_type" => $rule_type,
            ]);
            if ($checkOperator) {
                $result = true;
                if ($rule_type == 0)
                    return true;

            } else {
                $result = false;
                if ($rule_type == 1)
                    return false;
            }

        }
        return $result;
    }

    public static function checkRule($clue)
    {
        $rules = static::getRules();
        Log::debug("====> 开始识别规则");
        foreach ($rules as $rule) {
            Log::debug("========> 识别规则", ['规则名' => $rule['name'], '规则ID' => $rule['id'], '线索ID' => $clue['id']]);
            if ($rule['type'] === 0 || self::validateClueOfRule($clue, $rule->rules, $rule->rule_type)) {
                Log::debug('========> 识别成功', ['规则ID' => $rule['id']]);
                return $rule;
            }
        }
        return null;
    }


    public static function test($id = null)
    {
        $clue = $id ? Clue::find($id) : Clue::query()->first();
        if ($clue)
            $clue->mapToDispatchOfCheckRule();
    }

}
